﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Marmat.FrameWork
{
    internal static class MemberDescriptionExtensions
    {
        private static Dictionary<string, IEnumerable<XmlNode>> dic;

        ///// <summary>
        ///// 返回成员是否拥有xml注释的文本。
        ///// </summary>
        ///// <param name="member"></param>
        ///// <returns></returns>
        //public static string GetXmlDescription(this MemberInfo member)
        //{
        //    GetXmlDescription(member, out var description);
        //    return description;
        //}

        /// <summary>
        /// 获取成员的xml注释文本。
        /// </summary>
        /// <param name="member"></param>
        /// <param name="description"></param>
        /// <returns></returns>
        public static bool GetXmlDescription(this MemberInfo member, out string description)
        {
            bool result = false;
            description = string.Empty;
            if (dic is null)
                dic = new Dictionary<string, IEnumerable<XmlNode>>();
            string location = member.DeclaringType.Assembly.Location;
            IEnumerable<XmlNode> nodes = null;
            if (!dic.ContainsKey(location))
            {
                string path = Path.Combine(Path.GetDirectoryName(location), Path.GetFileNameWithoutExtension(location) + ".xml");
                if (File.Exists(path))
                {
                    var doc = new XmlDocument();
                    doc.Load(path);
                    nodes = doc.SelectSingleNode("/doc/members")?.ChildNodes.OfType<XmlElement>();
                }
                dic.Add(location, nodes);
            }
            else
                nodes = dic[location];
            if (nodes != null)
            {
                var node = nodes.FirstOrDefault(x =>
                {
                    string name = member.DeclaringType.FullName + "." + member.Name;
                    if (member is FieldInfo) name = "F:" + name;
                    else if (member is PropertyInfo) name = "P:" + name;
                    return Equals(x.Attributes["name"]?.Value, name);
                });
                result = node != null;
                if (node != null && node.ChildNodes.Count == 1 && node.ChildNodes[0].Name == "summary")
                    description = node.ChildNodes[0].InnerText.Trim();
            }
            return result;
        }
    }
}
